package com.yex.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yex.base.WalletOper;
import com.yex.base.WalletOperEnum;
import com.yex.base.ZeroResultException;
import com.yex.common.exception.RRException;
import com.yex.common.utils.PageUtils;
import com.yex.dao.WalletDao;
import com.yex.entity.UserEntity;
import com.yex.entity.WalletEntity;
import com.yex.entity.WalletLogEntity;
import com.yex.service.*;
import com.yex.utils.JsonResultVo;
import com.yex.utils.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;


@Service("walletService")
public class WalletServiceImpl extends ServiceImpl<WalletDao, WalletEntity> implements WalletService {

    @Autowired
    private WalletLogService walletLogService;
    @Autowired
    private LocaleMessageSourceService message;
    @Autowired
    private UserService userService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<WalletEntity> page = this.selectPage(
                new Query<WalletEntity>(params).getPage(),
                new EntityWrapper<WalletEntity>()
        );

        return new PageUtils(page);
    }


    @Override
    @Transactional
    public JsonResultVo updateTransferWallet(String mobile, String number, Integer userId) {

        UserEntity userEntity = userService.selectUserByMobile(mobile);
        if (userEntity == null) {
            return new JsonResultVo(message.getMessage("parameter_error"), -1);
        }

        WalletEntity walletTurnOut = baseMapper.selectByUserId(userId);
        if (walletTurnOut == null) {
            return new JsonResultVo(message.getMessage("parameter_error"), -1);
        }
        WalletOper walletOperTurnOut = new WalletOper();
        walletOperTurnOut.setUserId(userId);
        walletOperTurnOut.setAmount(new BigDecimal(number));
        walletOperTurnOut.setRemark("转出通证");
        walletOperTurnOut.setOper(WalletOperEnum.REDUCE);
        walletOperTurnOut.setId(walletTurnOut.getId());
        walletOperTurnOut.setTurnUserId(userEntity.getId());
        this.updateWallet(walletOperTurnOut);

        WalletEntity walletTurnInto = baseMapper.selectByUserId(userEntity.getId());
        WalletOper walletOperTurnInto = new WalletOper();
        walletOperTurnInto.setUserId(userEntity.getId());
        walletOperTurnInto.setAmount(new BigDecimal(number));
        walletOperTurnInto.setRemark("转入通证");
        walletOperTurnInto.setOper(WalletOperEnum.ADD);
        if (walletTurnInto != null) {
            walletOperTurnInto.setId(walletTurnInto.getId());
        }
        walletOperTurnInto.setTurnUserId(userId);
        this.updateWallet(walletOperTurnInto);

        return new JsonResultVo(message.getMessage("success"));
    }

    @Override
    public WalletEntity selectByUserId(Integer userId) {
        return baseMapper.selectByUserId(userId);
    }

    @Override
    @Transactional
    public boolean updateAddFrozen(WalletOper walletOper) {

        WalletEntity wallet = baseMapper.selectByUserId(walletOper.getUserId());
        WalletEntity walletEntity = new WalletEntity();
        walletEntity.setId(wallet.getId());
        walletEntity.setFrozen(walletOper.getAmount());
        int result = baseMapper.updateAddFrozen(walletEntity);
        if (result <= 0) {
            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
        }

        WalletLogEntity walletLogEntity = new WalletLogEntity();
        walletLogEntity.setUserId(walletOper.getUserId());

        walletLogEntity.setStatus(walletOper.getOper().ordinal());
        walletLogEntity.setRemark(walletOper.getRemark());
        walletLogEntity.setTotal(walletOper.getAmount());
        walletLogEntity.setWalletId(wallet.getId());
        walletLogEntity.setCreateTime(new Date());
        if (!walletLogService.insert(walletLogEntity)) {
            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
        }

        return true;
    }


    @Override
    @Transactional
    public JsonResultVo updateWallet(WalletOper walletOper) {
        WalletEntity walletEntity = new WalletEntity();
        walletEntity.setUserId(walletOper.getUserId());
        WalletEntity queryUser = baseMapper.selectByUserId(walletOper.getUserId());
        if (walletOper.getId() == null && WalletOperEnum.ADD == walletOper.getOper()
                && queryUser == null) {
            walletEntity.setTotal(walletOper.getAmount());
            int result = baseMapper.insertWallet(walletEntity);
            if (result <= 0) {
//                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
                throw new RRException("用户通证更新失败");
            }
            WalletEntity wallet = baseMapper.selectByUserId(walletOper.getUserId());
            WalletLogEntity walletLogEntity = new WalletLogEntity();
            walletLogEntity.setUserId(walletOper.getUserId());
            walletLogEntity.setStatus(walletOper.getOper().ordinal());
            walletLogEntity.setRemark(walletOper.getRemark());
            walletLogEntity.setTotal(walletOper.getAmount());
            walletLogEntity.setWalletId(wallet.getId());
            walletLogEntity.setCreateTime(new Date());
            if (!walletLogService.insert(walletLogEntity)) {
//                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
                throw new RRException("用户通证日志写入失败");
            }

            return result > 0 ? new JsonResultVo(message.getMessage("success"), 0) : new JsonResultVo(message.getMessage("fail"), -1);
        }

        walletEntity.setId(walletOper.getId());

        if (walletOper.getAmount().compareTo(BigDecimal.ZERO) < 0) {
//            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            throw new RRException("用户通证余额不足");
        }

        int result = -1;
        if (WalletOperEnum.FROZEN == walletOper.getOper()) {
            walletEntity.setFrozen(walletOper.getAmount());
            result = baseMapper.updateFrozen(walletEntity);
        } else if (WalletOperEnum.UNFRONZEN == walletOper.getOper()) {
            walletEntity.setFrozen(walletOper.getAmount());
            result = baseMapper.updateUnFrozen(walletEntity);
        } else if (WalletOperEnum.ADD == walletOper.getOper()) {
            walletEntity.setTotal(walletOper.getAmount());
            result = baseMapper.updateAdd(walletEntity);
        } else if (WalletOperEnum.REDUCE == walletOper.getOper()) {
            walletEntity.setTotal(walletOper.getAmount());
            result = baseMapper.updateReduce(walletEntity);
        } else if (WalletOperEnum.REDUCE_FROZEN == walletOper.getOper()) {
            walletEntity.setFrozen(walletOper.getAmount());
            result = baseMapper.updateReduceFrozen(walletEntity);
        }

        if (result <= 0) {
//            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            throw new RRException("用户通证更新失败");
        }

        WalletLogEntity walletLogEntity = new WalletLogEntity();
        walletLogEntity.setUserId(walletOper.getUserId());
        if (walletOper.getTurnUserId() != null) {
            walletLogEntity.setTurnUserId(walletOper.getTurnUserId());
        } else {
            walletLogEntity.setTurnUserId(0);
        }
        walletLogEntity.setStatus(walletOper.getOper().ordinal());
        walletLogEntity.setRemark(walletOper.getRemark());
        walletLogEntity.setTotal(walletOper.getAmount());
        walletLogEntity.setWalletId(walletOper.getId());
        walletLogEntity.setCreateTime(new Date());
        if (!walletLogService.insert(walletLogEntity)) {
//            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            throw new RRException("用户通证更新失败");
        }

        return new JsonResultVo(message.getMessage("success"));
    }


}
